#include <iostream>
#include <ostream>
/*

实现复数类，及其运算符重载
1. 区分成员运算符重载函数
和全局的运算符重载函数，重点在于全局的运算符重载函数，可以方便类型参数在运算符左边，自动类型转换
优先匹配成员运算符重载函数，然后匹配全局运算符重载函数，当提供全局运算符重载函数时，成员运算符重载函数则不需要提供了，其作用范围更广。
重点在于：看是否需要对象来调用


2. 前置后置自增自减运算符有两个版本
    operator++(int)  表示后置自增
    operator++()     表示前置自增

 */

class Complex {
public:
    Complex(int real = 0, int image = 0) : _real(real), _image(image) {
    }

    // 成员运算符重载，仅适用于 类+int 类+类
    Complex operator+(const Complex& other) {
        return {_real + other._real, _image + other._image};
    }

    // 前置自增
    Complex& operator++() {
        _real += 1;
        _image += 1;
        return *this;
    }

    // 后置自增
    Complex operator++(int) {
        return Complex(_real++, _image++);
    }

    void operator+=(const Complex& other) {
        _real += other._real;
        _image += other._image;
    }

    friend std::ostream& operator<<(std::ostream& os, const Complex& other);
    friend std::istream& operator>>(std::istream& is, Complex& other);
    friend Complex operator+(const Complex& a, const Complex& b);

private:
    int _real;
    int _image;
};

Complex operator+(const Complex& a, const Complex& b) {
    return {a._real + b._real, a._image + b._image};
}

std::ostream& operator<<(std::ostream& os, const Complex& other) {
    os << "real:" << other._real << ", image:" << other._image;
    return os;
}

std::istream& operator>>(std::istream& is, Complex& other) {
    is >> other._real >> other._image;
    return is;
}
int main() {
    Complex c1(10, 10);
    Complex c2(20, 20);
    std::cout << c1 + c2 << std::endl;
    std::cout << c1 + 20 << std::endl;  // 20 -> Complex 自动类型转换
    /* std::cout << 30 + c2 << std::endl;  //
     * 需要使用全局+运算符重载函数，才会有30->Complex的类型转换。 Invalid
     * operands to binary expression ('int' and 'Complex') */

    std::cout << 40 + c2
              << std::endl;  // 定义全局+运算符重载函数后，可以由40->Complex对象
    std::cout << "==========" << std::endl;

    Complex c3 = c1++;
    Complex c4 = ++c2;
    std::cout << c1 << std::endl;
    std::cout << c2 << std::endl;
    std::cout << c3 << std::endl;
    std::cout << c4 << std::endl;
    std::cout << "==========" << std::endl;

    c3 += c4;
    std::cout << c3 << std::endl;
    std::cout << "==========" << std::endl;

    std::cin >> c4;
    std::cout << c4 << std::endl;
}
